package studio.wetrack.accountService.auth.service.impl;

import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import studio.wetrack.accountService.auth.service.ShortUrlService;
import sun.misc.BASE64Encoder;

import java.util.Random;

/**
 * @author linzh
 * @date 2018-06-05 15:49
 */
public class ShortUrlServiceImpl implements ShortUrlService {
    private RedisTemplate<String, String> redisTemplate;
    private String baseUrl;
    private static String incrKey = "SHORT_URL_INCR";
    private static String urlMapKey = "SHORT_URL_MAP";
    private BASE64Encoder b64e = new BASE64Encoder();

    private ValueOperations<String, String> valueOperations;
    private HashOperations<String, String, String> hashOperations;


    public ShortUrlServiceImpl(RedisTemplate<String, String> redisTemplate, String baseUrl) {
        this.redisTemplate = redisTemplate;
        this.baseUrl = baseUrl;
        this.hashOperations = redisTemplate.opsForHash();
        this.valueOperations = redisTemplate.opsForValue();
    }

    @Override
    public String createBase64Url(String url) {
        long id;
        try {
            id = this.valueOperations.increment(incrKey, getRandom());
        } catch (InvalidDataAccessApiUsageException e) {
            id = 1;
            this.valueOperations.set(incrKey, id + "");
        }
        String shortUrl = b64e.encode(longToByteArray(id));
        shortUrl=shortUrl.replaceAll("/","#");
        this.hashOperations.put(urlMapKey,shortUrl,url);
        return this.baseUrl+shortUrl;
    }

//    public static void main(String[] args) {
//        BASE64Encoder b64e = new BASE64Encoder();
//        String shortUrl = b64e.encode(longToByteArray(1));
//        for (byte b : longToByteArray(1)) {
//            System.out.print(b);
//        }
//        System.out.println();
//        System.out.println(shortUrl);
//        System.out.println( b64e.encode("1".getBytes()));
//        System.out.println( b64e.encode("12".getBytes()));
//        System.out.println( b64e.encode("+~#".getBytes()));
//    }

    @Override
    public String getBase64Url(String shortUrl) {
        return this.hashOperations.get(urlMapKey, shortUrl);
    }

    private  byte[] longToByteArray(long a) {
        return new byte[]{
                (byte) ((a >> 16) & 0xFF),
                (byte) ((a >> 8) & 0xFF),
                (byte) (a & 0xFF)
        };
    }

    private int getRandom(){
        return ((Double) Math.floor(Math.random()*100+1)).intValue();
    }
}
